package main.java.com.lee.juc;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @Description 锁升级
 * @Author winston
 * @DateTime 2022/2/11
 */
public class LockUpgrade {
    static Map<String, String> common = new HashMap<>();
    public static void main(String[] args) throws InterruptedException {

        common.put("a", "aaa");
        common.put("b", "bbb");
        ReadWriteLock lock = new ReentrantReadWriteLock();
        Lock readLock = lock.readLock();
        Lock writeLock = lock.writeLock();

        Thread t4 = new Thread("t4") {
            @Override
            public void run() {
                try {
                    write(readLock, writeLock);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Thread t5 = new Thread("t5") {
            @Override
            public void run() {
                try {
                    read(readLock, writeLock);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

//        t1.start();
//        t2.start();
//        t3.start();
        t4.start();
        Thread.sleep(1000);
        t5.start();

//        t1.join();
//        t2.join();
//        t3.join();
        Thread.sleep(5000);
        t5.interrupt();
        t4.join();
        t5.join();

    }

    private static void read(Lock readLock, Lock writeLock) throws InterruptedException {
        readLock.lockInterruptibly();
        try {
            System.out.println(System.currentTimeMillis() +" :"+ Thread.currentThread().getName() + ": 读取资源" + common.get("a"));
            writeLock.lockInterruptibly();
            try {
                System.out.println("读锁升级写锁成功.");
            }finally {
                writeLock.unlock();
            }
            Thread.sleep(1000);
        } finally {
            readLock.unlock();
        }
    }

    private static void write(Lock readLock, Lock writeLock) throws InterruptedException {
        writeLock.lockInterruptibly();
        try {
            common.put("d","ddd");
            System.out.println(System.currentTimeMillis() +" :"+ Thread.currentThread().getName() + ": 写入资源d");
            readLock.lock();
            try {
                System.out.println("写锁降级读锁成功");
            }finally {
                readLock.unlock();
            }
        }finally {
            writeLock.unlock();
        }
    }
}
